import { isInterval } from '@/ayaka'
import { RoomEnergyState, RoomSafeState, RoomStateMemory } from './types'
import { CreepRoles } from '@/modules/structures/spawn/types'
import { WhiteList } from '@/setting'
import { isAllNpc } from '@/utils/war'
import StructureCache from '@/modules/structureCache'

/**
 * 房间状态管理
 */
export default class RoomStateManager {
    /**
     * 获取房间状态 memory
     */
    public static getMemory(room: Room) {
        if (!room.memory.state) room.memory.state = {}
        return room.memory.state
    }

    /**
     * 运行房间状态管理模块
     */
    public static run(room: MyRoom) {
        this.updateEnergyState(room)
        this.updateSafeState(room)
    }

    /**
     * 更新房间能量状态
     */
    public static updateEnergyState(room: Room) {
        if (!isInterval(31)) return

        const memory = RoomStateManager.getMemory(room)

        if (!global.roleStats[room.name]?.[CreepRoles.transporter]?.length) {
            memory.energy = RoomEnergyState.lack
            return
        }

        if (
            (room.storage?.store?.['energy'] || 0) > 1000 ||
            (room.terminal?.store?.['energy'] || 0) > 1000 ||
            global.roleStats[room.name]?.[CreepRoles.harvester]?.length
        ) {
            memory.energy = RoomEnergyState.normal
        } else {
            memory.energy = RoomEnergyState.lack
        }
    }

    /**
     * 更新房间安全状态，并将敌人挂载在房间对象上
     * TODO：考虑 pc
     */
    public static updateSafeState(room: MyRoom) {
        const memory = RoomStateManager.getMemory(room)
        if (!memory.safe) {
            memory.safe = {
                state: RoomSafeState.normal,
                lastEnemyTime: Game.time,
                searchEnemyInterval: room.controller.level * 10,
            }
        }

        if (Game.time - memory.safe.lastEnemyTime > 150 && !isInterval(RoomStateManager.getSearchEnemyInterval(room))) {
            return
        }

        if (room.controller.safeMode) {
            memory.safe.state = RoomSafeState.normal
            return
        }

        // 搜索敌人
        const creeps = room.find(FIND_CREEPS)
        const enemys = creeps.filter((creep) => !creep.my && !WhiteList.has(creep.owner.username))
        if (!enemys.length) {
            if (Game.time - memory.safe.lastEnemyTime > 150) {
                memory.safe.state = RoomSafeState.normal
            }
            return
        }

        room.enemys = enemys
        memory.safe.lastEnemyTime = Game.time

        if (isAllNpc(enemys)) {
            memory.safe.state = RoomSafeState.npcHarass
            return
        }

        memory.safe.state = RoomSafeState.underAttack
    }

    /**
     * 计算搜索敌人时间间隔
     */
    protected static getSearchEnemyInterval(room: MyRoom) {
        const safeMemory = RoomStateManager.getMemory(room).safe!
        if (isInterval(3000)) {
            safeMemory.searchEnemyInterval = Math.min(room.controller.level * 10, 50)
        }
        return safeMemory.searchEnemyInterval
    }
}

// ram 缺失且有敌人存在则开启 sf，TODO：改善 sf 开启机制
StructureCache.onStructMissing((room, types) => {
    // 低级房不开，防止高级房被钓
    if (room.controller.level < 4) return

    if (!room.enemys?.length) return

    if (types.includes(STRUCTURE_RAMPART)) {
        room.controller.activateSafeMode()
    }
})

declare global {
    interface RoomMemory {
        /**
         * 房间状态
         */
        state: Partial<RoomStateMemory>
    }

    interface Room {
        enemys: Creep[]
    }
}
